/************************************************************************************
 *
 * D++, A Lightweight C++ library for Discord
 *
 * Copyright 2022 Craig Edwards and D++ contributors
 * (https://github.com/brainboxdotcc/DPP/graphs/contributors)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ************************************************************************************/


/* Auto @generated by buildtools/make_coro_struct.php.
 *
 * DO NOT EDIT BY HAND!
 *
 * To re-generate this header file re-run the script!
 */
/**
 * @brief Create/overwrite global slash commands.
 * Any existing global slash commands will be deleted and replaced with these.
 *
 * @see dpp::cluster::global_bulk_command_create
 * @see https://discord.com/developers/docs/interactions/application-commands#bulk-overwrite-global-application-commands
 * @param commands Vector of slash commands to create/update.
 * overwriting existing commands that are registered globally for this application.
 * Commands that do not already exist will count toward daily application command create limits.
 * @return slashcommand_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_global_bulk_command_create(const std::vector<slashcommand> &commands);

/**
 * @brief Delete all existing global slash commands.
 * 
 * @see dpp::cluster::global_bulk_command_delete
 * @see https://discord.com/developers/docs/interactions/application-commands#bulk-overwrite-global-application-commands
 * @return slashcommand_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_global_bulk_command_delete();

/**
 * @brief Create a global slash command (a bot can have a maximum of 100 of these).
 * 
 * @see dpp::cluster::global_command_create
 * @see https://discord.com/developers/docs/interactions/application-commands#create-global-application-command
 * @param s Slash command to create
 * @return slashcommand returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_global_command_create(const slashcommand &s);

/**
 * @brief Get a global slash command
 *
 * @see dpp::cluster::global_command_get
 * @see https://discord.com/developers/docs/interactions/application-commands#get-global-application-command
 * @param id The ID of the slash command
 * @return slashcommand returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_global_command_get(snowflake id);

/**
 * @brief Delete a global slash command (a bot can have a maximum of 100 of these)
 *
 * @see dpp::cluster::global_command_delete
 * @see https://discord.com/developers/docs/interactions/application-commands#delete-global-application-command
 * @param id Slash command to delete
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_global_command_delete(snowflake id);

/**
 * @brief Edit a global slash command (a bot can have a maximum of 100 of these)
 *
 * @see dpp::cluster::global_command_edit
 * @see https://discord.com/developers/docs/interactions/application-commands#edit-global-application-command
 * @param s Slash command to change
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_global_command_edit(const slashcommand &s);

/**
 * @brief Get the application's global slash commands
 *
 * @see dpp::cluster::global_commands_get
 * @see https://discord.com/developers/docs/interactions/application-commands#get-global-application-commands
 * @return slashcommand_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_global_commands_get();

/**
 * @brief Create/overwrite guild slash commands.
 * Any existing guild slash commands on this guild will be deleted and replaced with these.
 *
 * @see dpp::cluster::guild_bulk_command_create
 * @see https://discord.com/developers/docs/interactions/application-commands#bulk-overwrite-guild-application-commands
 * @param commands Vector of slash commands to create/update.
 * New guild commands will be available in the guild immediately. If the command did not already exist, it will count toward daily application command create limits.
 * @param guild_id Guild ID to create/update the slash commands in
 * @return slashcommand_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_bulk_command_create(const std::vector<slashcommand> &commands, snowflake guild_id);

/**
 * @brief Delete all existing guild slash commands.
 * 
 * @see dpp::cluster::guild_bulk_command_delete
 * @see https://discord.com/developers/docs/interactions/application-commands#bulk-overwrite-global-application-commands
 * @param guild_id Guild ID to delete the slash commands in.
 * @return slashcommand_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_bulk_command_delete(snowflake guild_id);

/**
 * @brief Get all slash command permissions of a guild
 *
 * @see dpp::cluster::guild_commands_get_permissions
 * @see https://discord.com/developers/docs/interactions/application-commands#get-application-command-permissions
 * @param guild_id Guild ID to get the slash commands permissions for
 * @return guild_command_permissions_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_commands_get_permissions(snowflake guild_id);

/**
 * @brief Edit/Overwrite the permissions of all existing slash commands in a guild
 *
 * @note You can only add up to 10 permission overwrites for a command
 *
 * @see dpp::cluster::guild_bulk_command_edit_permissions
 * @see https://discord.com/developers/docs/interactions/application-commands#batch-edit-application-command-permissions
 * @warning The endpoint will overwrite all existing permissions for all commands of the application in a guild, including slash commands, user commands, and message commands. Meaning that if you forgot to pass a slash command, the permissions of it might be removed.
 * @param commands A vector of slash commands to edit/overwrite the permissions for
 * @param guild_id Guild ID to edit permissions of the slash commands in
 * @return guild_command_permissions_map returned object on completion
 * @deprecated This has been disabled with updates to Permissions v2. You can use guild_command_edit_permissions instead
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_bulk_command_edit_permissions(const std::vector<slashcommand> &commands, snowflake guild_id);

/**
 * @brief Create a slash command local to a guild
 *
 * @see dpp::cluster::guild_command_create
 * @see https://discord.com/developers/docs/interactions/application-commands#create-guild-application-command
 * @note Creating a command with the same name as an existing command for your application will overwrite the old command.
 * @param s Slash command to create
 * @param guild_id Guild ID to create the slash command in
 * @return slashcommand returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_command_create(const slashcommand &s, snowflake guild_id);

/**
 * @brief Delete a slash command local to a guild
 *
 * @see dpp::cluster::guild_command_delete
 * @see https://discord.com/developers/docs/interactions/application-commands#delete-guild-application-command
 * @param id Slash command to delete
 * @param guild_id Guild ID to delete the slash command in
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_command_delete(snowflake id, snowflake guild_id);

/**
 * @brief Edit slash command permissions of a guild
 *
 * @see dpp::cluster::guild_command_edit_permissions
 * @see https://discord.com/developers/docs/interactions/application-commands#edit-application-command-permissions
 * @note You can only add up to 10 permission overwrites for a command
 * @param s Slash command to edit the permissions for
 * @param guild_id Guild ID to edit the slash command in
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_command_edit_permissions(const slashcommand &s, snowflake guild_id);

/**
 * @brief Get a slash command of a guild
 *
 * @see dpp::cluster::guild_command_get
 * @see https://discord.com/developers/docs/interactions/application-commands#get-guild-application-command
 * @note The returned slash commands will not have permissions set, you need to use a permissions getter e.g. dpp::guild_commands_get_permissions to get the guild command permissions
 * @param id The ID of the slash command
 * @param guild_id Guild ID to get the slash command from
 * @return slashcommand returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_command_get(snowflake id, snowflake guild_id);

/**
 * @brief Get the permissions for a slash command of a guild
 *
 * @see dpp::cluster::guild_command_get_permissions
 * @see https://discord.com/developers/docs/interactions/application-commands#get-application-command-permissions
 * @param id The ID of the slash command to get the permissions for
 * @param guild_id Guild ID to get the permissions of
 * @return guild_command_permissions returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_command_get_permissions(snowflake id, snowflake guild_id);

/**
 * @brief Edit a slash command local to a guild
 *
 * @see dpp::cluster::guild_command_edit
 * @see https://discord.com/developers/docs/interactions/application-commands#edit-guild-application-command
 * @param s Slash command to edit
 * @param guild_id Guild ID to edit the slash command in
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_command_edit(const slashcommand &s, snowflake guild_id);

/**
 * @brief Get the application's slash commands for a guild
 *
 * @see dpp::cluster::guild_commands_get
 * @see https://discord.com/developers/docs/interactions/application-commands#get-guild-application-commands
 * @note The returned slash commands will not have permissions set, you need to use a permissions getter e.g. dpp::guild_commands_get_permissions to get the guild command permissions
 * @param guild_id Guild ID to get the slash commands for
 * @return slashcommand_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_commands_get(snowflake guild_id);

/**
 * @brief Respond to a slash command
 *
 * @see dpp::cluster::interaction_response_create
 * @see https://discord.com/developers/docs/interactions/receiving-and-responding#create-interaction-response
 * @param interaction_id Interaction id to respond to
 * @param token Token for the interaction webhook
 * @param r Response to send
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_interaction_response_create(snowflake interaction_id, const std::string &token, const interaction_response &r);

/**
 * @brief Edit response to a slash command
 *
 * @see dpp::cluster::interaction_response_edit
 * @see https://discord.com/developers/docs/interactions/receiving-and-responding#edit-original-interaction-response
 * @param token Token for the interaction webhook
 * @param m Message to send
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_interaction_response_edit(const std::string &token, const message &m);

/**
 * @brief Get the original response to a slash command
 *
 * @see dpp::cluster::interaction_response_get_original
 * @see https://discord.com/developers/docs/interactions/receiving-and-responding#get-original-interaction-response
 * @param token Token for the interaction webhook
 * @return message returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_interaction_response_get_original(const std::string &token);

/**
 * @brief Create a followup message for an interaction
 *
 * @see dpp::cluster::interaction_followup_create
 * @see https://discord.com/developers/docs/interactions/receiving-and-responding#create-interaction-response
 * @param token Token for the interaction webhook
 * @param m followup message to create
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_interaction_followup_create(const std::string &token, const message &m);

/**
 * @brief Edit original followup message for an interaction
 * This is an alias for cluster::interaction_response_edit
 * @see dpp::cluster::interaction_followup_edit_original
 * @see cluster::interaction_response_edit
 * 
 * @param token Token for the interaction webhook
 * @param m message to edit, the ID should be set
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_interaction_followup_edit_original(const std::string &token, const message &m);

/**
 * @brief Delete the initial interaction response
 *
 * @see dpp::cluster::interaction_followup_delete
 * @see https://discord.com/developers/docs/interactions/receiving-and-responding#delete-original-interaction-response
 * @param token Token for the interaction webhook
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_interaction_followup_delete(const std::string &token);

/**
 * @brief Edit followup message for an interaction
 * The message ID in the message you pass should be correctly set to that of a followup message you previously sent
 *
 * @see dpp::cluster::interaction_followup_edit
 * @see https://discord.com/developers/docs/interactions/receiving-and-responding#edit-followup-message
 * @param token Token for the interaction webhook
 * @param m message to edit, the ID should be set
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_interaction_followup_edit(const std::string &token, const message &m);

/**
 * @brief Get the followup message for an interaction
 *
 * @see dpp::cluster::interaction_followup_get
 * @see https://discord.com/developers/docs/interactions/receiving-and-responding#get-followup-message
 * @param token Token for the interaction webhook
 * @param message_id message to retrieve
 * @return message returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_interaction_followup_get(const std::string &token, snowflake message_id);

/**
 * @brief Get the original followup message for an interaction
 * This is an alias for cluster::interaction_response_get_original
 * @see dpp::cluster::interaction_followup_get_original
 * @see cluster::interaction_response_get_original
 * 
 * @param token Token for the interaction webhook
 * @return message returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_interaction_followup_get_original(const std::string &token);

/**
 * @brief Get all auto moderation rules for a guild
 * 
 * @param guild_id Guild id of the auto moderation rule
 * @return automod_rule_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_automod_rules_get(snowflake guild_id);

/**
 * @brief Get a single auto moderation rule
 * 
 * @param guild_id Guild id of the auto moderation rule
 * @param rule_id  Rule id to retrieve
 * @return automod_rule returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_automod_rule_get(snowflake guild_id, snowflake rule_id);

/**
 * @brief Create an auto moderation rule
 * 
 * @param guild_id Guild id of the auto moderation rule
 * @param r Auto moderation rule to create
 * @return automod_rule returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_automod_rule_create(snowflake guild_id, const automod_rule& r);

/**
 * @brief Edit an auto moderation rule
 * 
 * @param guild_id Guild id of the auto moderation rule
 * @param r Auto moderation rule to edit. The rule's id must be set.
 * @return automod_rule returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_automod_rule_edit(snowflake guild_id, const automod_rule& r);

/**
 * @brief Delete an auto moderation rule
 * 
 * @param guild_id Guild id of the auto moderation rule
 * @param rule_id Auto moderation rule id to delete
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_automod_rule_delete(snowflake guild_id, snowflake rule_id);

/**
 * @brief Create a channel
 * 
 * Create a new channel object for the guild. Requires the `MANAGE_CHANNELS` permission. If setting permission overwrites,
 * only permissions your bot has in the guild can be allowed/denied. Setting `MANAGE_ROLES` permission in channels is only possible
 * for guild administrators. Returns the new channel object on success. Fires a `Channel Create Gateway` event.
 * 
 * All parameters to this endpoint are optional excluding `name`
 * 
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @see dpp::cluster::channel_create
 * @see https://discord.com/developers/docs/resources/channel#create-channel
 * @param c Channel to create
 * @return channel returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_channel_create(const class channel &c);

/**
 * @brief Remove a permission from a channel
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @see dpp::cluster::channel_delete_permission
 * @see https://discord.com/developers/docs/resources/channel#delete-channel-permission
 * @param c Channel to remove permission from
 * @param overwrite_id Overwrite to remove, user or channel ID
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_channel_delete_permission(const class channel &c, snowflake overwrite_id);

/**
 * @brief Delete a channel
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @see dpp::cluster::channel_delete
 * @see https://discord.com/developers/docs/resources/channel#deleteclose-channel
 * @param channel_id Channel id to delete
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_channel_delete(snowflake channel_id);

/**
 * @brief Edit a channel's permissions
 *
 * @see dpp::cluster::channel_edit_permissions
 * @see https://discord.com/developers/docs/resources/channel#edit-channel-permissions
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @param c Channel to set permissions for
 * @param overwrite_id Overwrite to change (a user or role ID)
 * @param allow Bitmask of allowed permissions (refer to enum dpp::permissions)
 * @param deny Bitmask of denied permissions (refer to enum dpp::permissions)
 * @param member true if the overwrite_id is a user id, false if it is a channel id
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_channel_edit_permissions(const class channel &c, const snowflake overwrite_id, const uint64_t allow, const uint64_t deny, const bool member);

/**
 * @brief Edit a channel's permissions
 *
 * @see dpp::cluster::channel_edit_permissions
 * @see https://discord.com/developers/docs/resources/channel#edit-channel-permissions
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @param channel_id ID of the channel to set permissions for
 * @param overwrite_id Overwrite to change (a user or role ID)
 * @param allow Bitmask of allowed permissions (refer to enum dpp::permissions)
 * @param deny Bitmask of denied permissions (refer to enum dpp::permissions)
 * @param member true if the overwrite_id is a user id, false if it is a channel id
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_channel_edit_permissions(const snowflake channel_id, const snowflake overwrite_id, const uint64_t allow, const uint64_t deny, const bool member);

/**
 * @brief Edit multiple channels positions
 * 
 * Modify the positions of a set of channel objects for the guild.
 * Requires `MANAGE_CHANNELS` permission. Fires multiple `Channel Update Gateway` events.
 * Only channels to be modified are required.
 *
 * @see dpp::cluster::channel_edit_positions
 * @see https://discord.com/developers/docs/resources/guild#modify-guild-channel-positions
 * @param c Channel to change the position for
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_channel_edit_positions(const std::vector<channel> &c);

/**
 * @brief Edit a channel
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @see dpp::cluster::channel_edit
 * @see https://discord.com/developers/docs/resources/channel#modify-channel
 * @param c Channel to edit/update
 * @return channel returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_channel_edit(const class channel &c);

/**
 * @brief Follow an announcement (news) channel
 * @see dpp::cluster::channel_follow_news
 * @see https://discord.com/developers/docs/resources/channel#follow-news-channel
 * @param c Channel id to follow
 * @param target_channel_id Channel to subscribe the channel to
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_channel_follow_news(const class channel &c, snowflake target_channel_id);

/**
 * @brief Get a channel
 *
 * @see dpp::cluster::channel_get
 * @see https://discord.com/developers/docs/resources/channel#get-channel
 * @param c Channel ID to retrieve
 * @return channel returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_channel_get(snowflake c);

/**
 * @brief Create invite for a channel
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @see dpp::cluster::channel_invite_create
 * @see https://discord.com/developers/docs/resources/channel#create-channel-invite
 * @param c Channel to create an invite on
 * @param i Invite to create
 * @return invite returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_channel_invite_create(const class channel &c, const class invite &i);

/**
 * @brief Get invites for a channel
 *
 * @see dpp::cluster::channel_invites_get
 * @see https://discord.com/developers/docs/resources/invite#get-invites
 * @param c Channel to get invites for
 * @return invite_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_channel_invites_get(const class channel &c);

/**
 * @brief Trigger channel typing indicator
 * @see dpp::cluster::channel_typing
 * @see https://discord.com/developers/docs/resources/channel#trigger-typing-indicator
 * @param c Channel to set as typing on
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_channel_typing(const class channel &c);

/**
 * @brief Trigger channel typing indicator
 * @see dpp::cluster::channel_typing
 * @see https://discord.com/developers/docs/resources/channel#trigger-typing-indicator
 * @param cid Channel ID to set as typing on
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_channel_typing(snowflake cid);

/**
 * @brief Get all channels for a guild
 *
 * @see dpp::cluster::channels_get
 * @see https://discord.com/developers/docs/resources/channel#get-channels
 * @param guild_id Guild ID to retrieve channels for
 * @return channel_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_channels_get(snowflake guild_id);

/**
 * @brief Set the status of a voice channel.
 *
 * @see dpp::cluster::channel_set_voice_status
 * @see https://github.com/discord/discord-api-docs/pull/6400 (please replace soon).
 * @param channel_id The channel to update.
 * @param status The new status for the channel.
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_channel_set_voice_status(snowflake channel_id, const std::string& status);

/**
 * @brief Create a dm channel
 * @see dpp::cluster::create_dm_channel
 * @see https://discord.com/developers/docs/resources/user#create-dm
 * @param user_id User ID to create DM channel with
 * @return channel returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_create_dm_channel(snowflake user_id);

/**
 * @brief Get current user DM channels
 * 
 * @return channel_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_current_user_get_dms();

/**
 * @brief Create a direct message, also create the channel for the direct message if needed
 *
 * @see dpp::cluster::direct_message_create
 * @see https://discord.com/developers/docs/resources/user#create-dm
 * @see dpp::cluster::direct_message_create
 * @see https://discord.com/developers/docs/resources/channel#create-message
 * @param user_id User ID of user to send message to
 * @param m Message object
 * @return message returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_direct_message_create(snowflake user_id, const message &m);

/**
 * @brief Adds a recipient to a Group DM using their access token
 * @see dpp::cluster::gdm_add
 * @see https://discord.com/developers/docs/resources/channel#group-dm-add-recipient
 * @param channel_id Channel id to add group DM recipients to
 * @param user_id User ID to add
 * @param access_token Access token from OAuth2
 * @param nick Nickname of user to apply to the chat
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_gdm_add(snowflake channel_id, snowflake user_id, const std::string &access_token, const std::string &nick);

/**
 * @brief Removes a recipient from a Group DM
 * @see dpp::cluster::gdm_remove
 * @see https://discord.com/developers/docs/resources/channel#group-dm-remove-recipient
 * @param channel_id Channel ID of group DM
 * @param user_id User ID to remove from group DM
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_gdm_remove(snowflake channel_id, snowflake user_id);

/**
 * @brief Create single emoji.
 * You must ensure that the emoji passed contained image data using the emoji::load_image() method.
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 *
 * @see dpp::cluster::guild_emoji_create
 * @see https://discord.com/developers/docs/resources/emoji#create-guild-emoji
 * @param guild_id Guild ID to create emoji om
 * @param newemoji Emoji to create
 * @return emoji returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_emoji_create(snowflake guild_id, const class emoji& newemoji);

/**
 * @brief Delete a guild emoji
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 *
 * @see dpp::cluster::guild_emoji_delete
 * @see https://discord.com/developers/docs/resources/emoji#delete-guild-emoji
 * @param guild_id Guild ID to delete emoji on
 * @param emoji_id Emoji ID to delete
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_emoji_delete(snowflake guild_id, snowflake emoji_id);

/**
 * @brief Edit a single emoji.
 * 
 * You must ensure that the emoji passed contained image data using the emoji::load_image() method.
 * @see dpp::cluster::guild_emoji_edit
 * @see https://discord.com/developers/docs/resources/emoji#modify-guild-emoji
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @param guild_id Guild ID to edit emoji on
 * @param newemoji Emoji to edit
 * @return emoji returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_emoji_edit(snowflake guild_id, const class emoji& newemoji);

/**
 * @brief Get a single emoji
 *
 * @see dpp::cluster::guild_emoji_get
 * @see https://discord.com/developers/docs/resources/emoji#get-guild-emoji
 * @param guild_id Guild ID to get emoji for
 * @param emoji_id Emoji ID to get
 * @return emoji returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_emoji_get(snowflake guild_id, snowflake emoji_id);

/**
 * @brief Get all emojis for a guild
 *
 * @see dpp::cluster::guild_emojis_get
 * @see https://discord.com/developers/docs/resources/emoji#list-guild-emojis
 * @param guild_id Guild ID to get emojis for
 * @return emoji_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_emojis_get(snowflake guild_id);

/**
 * @brief List all Application Emojis
 *
 * @see dpp::cluster::application_emojis_get
 * @see https://discord.com/developers/docs/resources/emoji#list-application-emojis
 * @return emoji_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_application_emojis_get();

/**
 * @brief Get an Application Emoji
 *
 * @see dpp::cluster::application_emoji_get
 * @see https://discord.com/developers/docs/resources/emoji#get-application-emoji
 * @param emoji_id The ID of the Emoji to get.
 * @return emoji returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_application_emoji_get(snowflake emoji_id);

/**
 * @brief Create an Application Emoji
 *
 * @see dpp::cluster::application_emoji_create
 * @see https://discord.com/developers/docs/resources/emoji#create-application-emoji
 * @param newemoji The emoji to create
 * @return emoji returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_application_emoji_create(const class emoji& newemoji);

/**
 * @brief Edit an Application Emoji
 *
 * @see dpp::cluster::application_emoji_edit
 * @see https://discord.com/developers/docs/resources/emoji#modify-application-emoji
 * @param newemoji The emoji to edit
 * @return emoji returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_application_emoji_edit(const class emoji& newemoji);

/**
 * @brief Delete an Application Emoji
 *
 * @see dpp::cluster::application_emoji_delete
 * @see https://discord.com/developers/docs/resources/emoji#delete-application-emoji
 * @param emoji_id The emoji's ID to delete.
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_application_emoji_delete(snowflake emoji_id);

/**
 * @brief Returns all entitlements for a given app, active and expired.
 *
 * @see dpp::cluster::entitlements_get
 * @see https://discord.com/developers/docs/monetization/entitlements#list-entitlements
 * @param user_id User ID to look up entitlements for.
 * @param sku_ids List of SKU IDs to check entitlements for.
 * @param before_id Retrieve entitlements before this entitlement ID.
 * @param after_id Retrieve entitlements after this entitlement ID.
 * @param limit Number of entitlements to return, 1-100 (default 100).
 * @param guild_id Guild ID to look up entitlements for.
 * @param exclude_ended Whether ended entitlements should be excluded from the search.
 * @return entitlement_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_entitlements_get(snowflake user_id = 0, const std::vector<snowflake>& sku_ids = {}, snowflake before_id = 0, snowflake after_id = 0, uint8_t limit = 100, snowflake guild_id = 0, bool exclude_ended = false);

/**
 * @brief Creates a test entitlement to a given SKU for a given guild or user.
 * Discord will act as though that user or guild has entitlement to your premium offering.
 *
 * @see dpp::cluster::entitlement_test_create
 * @see https://discord.com/developers/docs/monetization/entitlements#create-test-entitlement
 * @param new_entitlement The entitlement to create.
 * Make sure your dpp::entitlement_type (inside your dpp::entitlement object) matches the type of the owner_id
 * (if type is guild, owner_id is a guild id), otherwise it won't work!
 * @return entitlement returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_entitlement_test_create(const class entitlement& new_entitlement);

/**
 * @brief Deletes a currently-active test entitlement.
 * Discord will act as though that user or guild no longer has entitlement to your premium offering.
 *
 * @see dpp::cluster::entitlement_test_delete
 * @see https://discord.com/developers/docs/monetization/entitlements#delete-test-entitlement
 * @param entitlement_id The test entitlement to delete.
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_entitlement_test_delete(snowflake entitlement_id);

/**
 * @brief For One-Time Purchase consumable SKUs, marks a given entitlement for the user as consumed.
 *
 * @see dpp::cluster::entitlement_consume
 * @see https://discord.com/developers/docs/monetization/entitlements#consume-an-entitlement
 * @param entitlement_id The entitlement to mark as consumed.
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_entitlement_consume(snowflake entitlement_id);

/**
 * @brief Get the gateway information for the bot using the token
 * @see dpp::cluster::get_gateway_bot
 * @see https://discord.com/developers/docs/topics/gateway#get-gateway-bot
 * @return gateway returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_get_gateway_bot();

/**
 * @brief Modify current member
 *
 * Modifies the current member in a guild.
 * Fires a `Guild Member Update` Gateway event.
 *
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @see dpp::cluster::guild_current_member_edit
 * @see https://discord.com/developers/docs/resources/guild#modify-current-member
 * @param guild_id Guild ID to change on
 * @param nickname New nickname, or empty string to clear nickname.
 * @param banner_blob New banner, or empty string to clear banner.
 * @param banner_type Type of image for new banner.
 * @param avatar_blob New avatar, or empty string to clear avatar.
 * @param avatar_type Type of image for new avatar.
 * @param bio New bio, or empty string to clear bio
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_current_member_edit(snowflake guild_id, const std::string& nickname, const std::string& banner_blob, const image_type banner_type, const std::string& avatar_blob, const image_type avatar_type, const std::string& bio);

/**
 * @brief Get the audit log for a guild
 *
 * @see dpp::cluster::guild_auditlog_get
 * @see https://discord.com/developers/docs/resources/audit-log#get-guild-audit-log
 * @param guild_id Guild to get the audit log of
 * @param user_id Entries from a specific user ID. Set this to `0` will fetch any user
 * @param action_type Entries for a specific dpp::audit_type. Set this to `0` will fetch any type
 * @param before Entries with ID less than a specific audit log entry ID. Used for paginating
 * @param after Entries with ID greater than a specific audit log entry ID. Used for paginating
 * @param limit Maximum number of entries (between 1-100) to return
 * @return auditlog returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_auditlog_get(snowflake guild_id, snowflake user_id, uint32_t action_type, snowflake before, snowflake after, uint32_t limit);

/**
 * @brief Add guild ban
 *
 * Create a guild ban, and optionally delete previous messages sent by the banned user.
 * Requires the `BAN_MEMBERS` permission. Fires a `Guild Ban Add` Gateway event.
 * @see dpp::cluster::guild_ban_add
 * @see https://discord.com/developers/docs/resources/guild#create-guild-ban
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @param guild_id Guild ID to add ban to
 * @param user_id User ID to ban
 * @param delete_message_seconds How many seconds to delete messages for, between 0 and 604800 (7 days). Defaults to 0
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_ban_add(snowflake guild_id, snowflake user_id, uint32_t delete_message_seconds = 0);

/**
 * @brief Delete guild ban
 * 
 * Remove the ban for a user. Requires the `BAN_MEMBERS` permissions.
 * Fires a Guild Ban Remove Gateway event.
 * @see dpp::cluster::guild_ban_delete
 * @see https://discord.com/developers/docs/resources/guild#remove-guild-ban
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @param guild_id Guild to delete ban from
 * @param user_id User ID to delete ban for
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_ban_delete(snowflake guild_id, snowflake user_id);

/**
 * @brief Create a guild
 * 
 * Create a new guild. Returns a guild object on success. `Fires a Guild Create Gateway` event.
 * 
 * When using the roles parameter, the first member of the array is used to change properties of the guild's everyone role.
 * If you are trying to bootstrap a guild with additional roles, keep this in mind. The required id field within each role object is an
 * integer placeholder, and will be replaced by the API upon consumption. Its purpose is to allow you to overwrite a role's permissions
 * in a channel when also passing in channels with the channels array.
 * When using the channels parameter, the position field is ignored, and none of the default channels are created. The id field within
 * each channel object may be set to an integer placeholder, and will be replaced by the API upon consumption. Its purpose is to
 * allow you to create `GUILD_CATEGORY` channels by setting the `parent_id` field on any children to the category's id field.
 * Category channels must be listed before any children.
 *
 * @see dpp::cluster::guild_create
 * @see https://discord.com/developers/docs/resources/guild#create-guild
 * @note The region field is deprecated and is replaced by channel.rtc_region. This endpoint can be used only by bots in less than 10 guilds.
 * @param g Guild to create
 * @return guild returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_create(const class guild &g);

/**
 * @brief Delete a guild
 * 
 * Delete a guild permanently. User must be owner. Fires a `Guild Delete Gateway` event.
 *
 * @see dpp::cluster::guild_delete
 * @see https://discord.com/developers/docs/resources/guild#delete-guild
 * @param guild_id Guild ID to delete
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_delete(snowflake guild_id);

/**
 * @brief Delete guild integration
 * 
 * Delete the attached integration object for the guild. Deletes any associated webhooks and kicks the associated bot if there is one.
 * Requires the `MANAGE_GUILD` permission. Fires a Guild Integrations Update Gateway event.
 * 
 * @see dpp::cluster::guild_delete_integration
 * @see https://discord.com/developers/docs/resources/guild#delete-guild-integration
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @param guild_id Guild ID to delete integration for
 * @param integration_id Integration ID to delete
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_delete_integration(snowflake guild_id, snowflake integration_id);

/**
 * @brief Edit a guild
 * 
 * Modify a guild's settings. Requires the `MANAGE_GUILD` permission. Returns the updated guild object on success.
 * Fires a `Guild Update Gateway` event.
 * 
 * @see dpp::cluster::guild_edit
 * @see https://discord.com/developers/docs/resources/guild#modify-guild
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @param g Guild to edit
 * @return guild returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_edit(const class guild &g);

/**
 * @brief Edit guild widget
 * 
 * Requires the `MANAGE_GUILD` permission.
 *
 * @see dpp::cluster::guild_edit_widget
 * @see https://discord.com/developers/docs/resources/guild#modify-guild-widget
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @param guild_id Guild ID to edit widget for
 * @param gw New guild widget information
 * @return guild_widget returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_edit_widget(snowflake guild_id, const class guild_widget &gw);

/**
 * @brief Get single guild ban
 * 
 * Requires the `BAN_MEMBERS` permission.
 * @see dpp::cluster::guild_get_ban
 * @see https://discord.com/developers/docs/resources/guild#get-guild-ban
 * @param guild_id Guild ID to get ban for
 * @param user_id User ID of ban to retrieve
 * @return ban returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_get_ban(snowflake guild_id, snowflake user_id);

/**
 * @brief Get guild ban list
 * 
 * Requires the `BAN_MEMBERS` permission.
 * @see dpp::cluster::guild_get_bans
 * @see https://discord.com/developers/docs/resources/guild#get-guild-bans
 * @note Provide a user ID to `before` and `after` for pagination. Users will always be returned in ascending order by the user ID. If both before and after are provided, only before is respected.
 * @param guild_id Guild ID to get bans for
 * @param before If non-zero, all bans for user ids before this user id will be returned up to the limit
 * @param after if non-zero, all bans for user ids after this user id will be returned up to the limit
 * @param limit the maximum number of bans to retrieve in this call up to a maximum of 1000
 * @return ban_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_get_bans(snowflake guild_id, snowflake before, snowflake after, snowflake limit);


[[nodiscard]] async<confirmation_callback_t> co_guild_get(snowflake guild_id);

/**
 * @brief Get guild integrations
 * 
 * Requires the `MANAGE_GUILD` permission.
 *
 * @see dpp::cluster::guild_get_integrations
 * @see https://discord.com/developers/docs/resources/guild#get-guild-integrations
 * @param guild_id Guild ID to get integrations for
 * @return integration_map returned object on completion
 *
 * @note This endpoint returns a maximum of 50 integrations. If a guild has more integrations, they cannot be accessed.
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_get_integrations(snowflake guild_id);


[[nodiscard]] async<confirmation_callback_t> co_guild_get_preview(snowflake guild_id);

/**
 * @brief Get guild vanity url, if enabled
 * 
 * Returns a partial dpp::invite object for guilds with that feature enabled. Requires the `MANAGE_GUILD` permission. code will be null if a vanity url for the guild is not set.
 * @see dpp::cluster::guild_get_vanity
 * @see https://discord.com/developers/docs/resources/guild#get-guild-vanity-url
 * @param guild_id Guild to get vanity URL for
 * @return invite returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_get_vanity(snowflake guild_id);

/**
 * @brief Get guild widget
 * 
 * Requires the `MANAGE_GUILD` permission.
 *
 * @see dpp::cluster::guild_get_widget
 * @see https://discord.com/developers/docs/resources/guild#get-guild-widget
 * @param guild_id Guild ID to get widget for
 * @return guild_widget returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_get_widget(snowflake guild_id);

/**
 * @brief Modify guild integration
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 *
 * @see dpp::cluster::guild_modify_integration
 * @see https://discord.com/developers/docs/resources/guild#modify-guild-integration
 * @param guild_id Guild ID to modify integration for
 * @param i Integration to modify
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_modify_integration(snowflake guild_id, const class integration &i);

/**
 * @brief Get prune counts
 * 
 * Returns a prune object indicating the number of members that would be removed in a prune operation. Requires the `KICK_MEMBERS`
 * permission. By default, prune will not remove users with roles. You can optionally include specific roles in your prune by providing the
 * include_roles parameter. Any inactive user that has a subset of the provided role(s) will be counted in the prune and users with additional
 * roles will not.
 *
 * @see dpp::cluster::guild_get_prune_counts
 * @see https://discord.com/developers/docs/resources/guild#get-guild-prune-count
 * @param guild_id Guild ID to count for pruning
 * @param pruneinfo Pruning info
 * @return prune returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_get_prune_counts(snowflake guild_id, const struct prune& pruneinfo);

/**
 * @brief Begin guild prune
 * 
 * Begin a prune operation. Requires the `KICK_MEMBERS` permission. Returns a prune object indicating the number of members
 * that were removed in the prune operation. For large guilds it's recommended to set the `compute_prune_count` option to false, forcing
 * 'pruned' to 0. Fires multiple `Guild Member Remove` Gateway events.
 * By default, prune will not remove users with roles. You can optionally include specific roles in your prune by providing the `include_roles`
 * parameter. Any inactive user that has a subset of the provided role(s) will be included in the prune and users with additional roles will not.
 * 
 * @see dpp::cluster::guild_begin_prune
 * @see https://discord.com/developers/docs/resources/guild#begin-guild-prune
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @param guild_id Guild ID to prune
 * @param pruneinfo Pruning info
 * @return prune returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_begin_prune(snowflake guild_id, const struct prune& pruneinfo);

/**
 * @brief Change current user nickname
 * 
 * Modifies the nickname of the current user in a guild.
 * Fires a `Guild Member Update` Gateway event.
 * 
 * @deprecated Deprecated in favor of Modify Current Member. Will be replaced by dpp::cluster::guild_current_member_edit
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @see dpp::cluster::guild_set_nickname
 * @see https://discord.com/developers/docs/resources/guild#modify-current-user-nick
 * @param guild_id Guild ID to change nickname on
 * @param nickname New nickname, or empty string to clear nickname
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_set_nickname(snowflake guild_id, const std::string &nickname);

/**
 * @brief Sync guild integration
 *
 * @see dpp::cluster::guild_sync_integration
 * @see https://discord.com/developers/docs/resources/guild#sync-guild-integration
 * @param guild_id Guild ID to sync integration on
 * @param integration_id Integration ID to synchronise
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_sync_integration(snowflake guild_id, snowflake integration_id);

/**
 * @brief Get the guild's onboarding configuration
 *
 * @see dpp::cluster::guild_get_onboarding
 * @see https://discord.com/developers/docs/resources/guild#get-guild-onboarding
 * @param guild_id The guild to pull the onboarding configuration from.
 * @return onboarding returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_get_onboarding(snowflake guild_id);

/**
 * @brief Edit the guild's onboarding configuration
 *
 * Requires the `MANAGE_GUILD` and `MANAGE_ROLES` permissions.
 *
 * @note Onboarding enforces constraints when enabled. These constraints are that there must be at least 7 Default Channels and at least 5 of them must allow sending messages to the \@everyone role. The `onboarding::mode` field modifies what is considered when enforcing these constraints.
 *
 * @see dpp::cluster::guild_edit_onboarding
 * @see https://discord.com/developers/docs/resources/guild#modify-guild-onboarding
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @param o The onboarding object
 * @return onboarding returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_edit_onboarding(const struct onboarding& o);

/**
 * @brief Get the guild's welcome screen
 *
 * If the welcome screen is not enabled, the `MANAGE_GUILD` permission is required.
 *
 * @see dpp::cluster::guild_get_welcome_screen
 * @see https://discord.com/developers/docs/resources/guild#get-guild-welcome-screen
 * @param guild_id The guild ID to get the welcome screen from
 * @return dpp::welcome_screen returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_get_welcome_screen(snowflake guild_id);

/**
 * @brief Edit the guild's welcome screen
 *
 * Requires the `MANAGE_GUILD` permission. May fire a `Guild Update` Gateway event.
 *
 * @see dpp::cluster::guild_edit_welcome_screen
 * @see https://discord.com/developers/docs/resources/guild#modify-guild-welcome-screen
 * @param guild_id The guild ID to edit the welcome screen for
 * @param welcome_screen The welcome screen
 * @param enabled Whether the welcome screen should be enabled or disabled
 * @return dpp::welcome_screen returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_edit_welcome_screen(snowflake guild_id, const struct welcome_screen& welcome_screen, bool enabled);

/**
 * @brief Add guild member. Needs a specific oauth2 scope, from which you get the access_token.
 * 
 * Adds a user to the guild, provided you have a valid oauth2 access token for the user with the guilds.join scope.
 * Returns the guild_member, which is defaulted if the user is already a member of the guild. Fires a `Guild Member Add` Gateway event.
 * 
 * For guilds with Membership Screening enabled, this endpoint will default to adding new members as pending in the guild member object.
 * Members that are pending will have to complete membership screening before they become full members that can talk.
 * 
 * @note All parameters to this endpoint except for access_token are optional.
 * The bot must be a member of the guild with `CREATE_INSTANT_INVITE` permission.
 * @see dpp::cluster::guild_add_member
 * @see https://discord.com/developers/docs/resources/guild#add-guild-member
 * @param gm Guild member to add
 * @param access_token Access token from Oauth2 scope
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_add_member(const guild_member& gm, const std::string &access_token);

/**
 * @brief Edit the properties of an existing guild member
 * 
 * Modify attributes of a guild member. Returns the guild_member. Fires a `Guild Member Update` Gateway event.
 * To remove a timeout, set the `communication_disabled_until` to a non-zero time in the past, e.g. 1.
 * When moving members to channels, the API user must have permissions to both connect to the channel and have the `MOVE_MEMBERS` permission.
 * For moving and disconnecting users from voice, use dpp::cluster::guild_member_move.
 * @see dpp::cluster::guild_edit_member
 * @see https://discord.com/developers/docs/resources/guild#modify-guild-member
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @param gm Guild member to edit
 * @return guild_member returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_edit_member(const guild_member& gm);

/**
 * @brief Get a guild member
 * @see dpp::cluster::guild_get_member
 * @see https://discord.com/developers/docs/resources/guild#get-guild-member
 * @param guild_id Guild ID to get member for
 * @param user_id User ID of member to get
 * @return guild_member returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_get_member(snowflake guild_id, snowflake user_id);

/**
 * @brief Get all guild members
 * 
 * @note This endpoint is restricted according to whether the `GUILD_MEMBERS` Privileged Intent is enabled for your application.
 * @see dpp::cluster::guild_get_members
 * @see https://discord.com/developers/docs/resources/guild#get-guild-members
 * @param guild_id Guild ID to get all members for
 * @param limit max number of members to return (1-1000)
 * @param after the highest user id in the previous page
 * @return guild_member_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_get_members(snowflake guild_id, uint16_t limit, snowflake after);

/**
 * @brief Add role to guild member
 * 
 * Adds a role to a guild member. Requires the `MANAGE_ROLES` permission.
 * Fires a `Guild Member Update` Gateway event.
 * @see dpp::cluster::guild_member_add_role
 * @see https://discord.com/developers/docs/resources/guild#add-guild-member-role
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @param guild_id Guild ID to add a role to
 * @param user_id User ID to add role to
 * @param role_id Role ID to add to the user
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_member_add_role(snowflake guild_id, snowflake user_id, snowflake role_id);

/**
 * @brief Remove (kick) a guild member
 * 
 * Remove a member from a guild. Requires `KICK_MEMBERS` permission.
 * Fires a `Guild Member Remove` Gateway event.
 * @see dpp::cluster::guild_member_delete
 * @see https://discord.com/developers/docs/resources/guild#remove-guild-member
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @deprecated Replaced by dpp::cluster::guild_member_kick
 * @param guild_id Guild ID to kick member from
 * @param user_id User ID to kick
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_member_delete(snowflake guild_id, snowflake user_id);

/**
 * @brief Remove (kick) a guild member
 *  
 * Remove a member from a guild. Requires `KICK_MEMBERS` permission.
 * Fires a `Guild Member Remove` Gateway event.
 * @see dpp::cluster::guild_member_kick
 * @see https://discord.com/developers/docs/resources/guild#remove-guild-member
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @param guild_id Guild ID to kick member from
 * @param user_id User ID to kick
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_member_kick(snowflake guild_id, snowflake user_id);

/**
 * @brief Set the timeout of a guild member
 *
 * Fires a `Guild Member Update` Gateway event.
 * @see dpp::cluster::guild_member_timeout
 * @see https://discord.com/developers/docs/resources/guild#modify-guild-member
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @param guild_id Guild ID to timeout the member in
 * @param user_id User ID to set the timeout for
 * @param communication_disabled_until The timestamp when the user's timeout will expire (up to 28 days in the future). Set to 0 to remove the timeout
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_member_timeout(snowflake guild_id, snowflake user_id, time_t communication_disabled_until);

/**
 * @brief Remove the timeout of a guild member.
 * A shortcut for guild_member_timeout(guild_id, user_id, 0, callback)
 * Fires a `Guild Member Update` Gateway event.
 * @see dpp::cluster::guild_member_timeout_remove
 * @see https://discord.com/developers/docs/resources/guild#modify-guild-member
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @param guild_id Guild ID to remove the member timeout from
 * @param user_id User ID to remove the timeout for
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_member_timeout_remove(snowflake guild_id, snowflake user_id);

/**
 * @brief Remove role from guild member
 * 
 * Removes a role from a guild member. Requires the `MANAGE_ROLES` permission.
 * Fires a `Guild Member Update` Gateway event.
 * @see dpp::cluster::guild_member_delete_role
 * @see https://discord.com/developers/docs/resources/guild#remove-guild-member-role
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @param guild_id Guild ID to remove role from user on
 * @param user_id User ID to remove role from
 * @param role_id Role to remove
 * @return confirmation returned object on completion
 * @deprecated Use dpp::cluster::guild_member_remove_role instead
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_member_delete_role(snowflake guild_id, snowflake user_id, snowflake role_id);

/**
 * @brief Remove role from guild member
 *
 * Removes a role from a guild member. Requires the `MANAGE_ROLES` permission.
 * Fires a `Guild Member Update` Gateway event.
 * @see dpp::cluster::guild_member_remove_role
 * @see https://discord.com/developers/docs/resources/guild#remove-guild-member-role
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @param guild_id Guild ID to remove role from user on
 * @param user_id User ID to remove role from
 * @param role_id Role to remove
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_member_remove_role(snowflake guild_id, snowflake user_id, snowflake role_id);

/**
 * @brief Moves the guild member to a other voice channel, if member is connected to one.
 * Set the `channel_id` to `0` to disconnect the user.
 *
 * Fires a `Guild Member Update` Gateway event.
 * @note When moving members to channels, the API user __must__ have permissions to both connect to the channel and have the `MOVE_MEMBERS` permission.
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @see dpp::cluster::guild_member_move
 * @see https://discord.com/developers/docs/resources/guild#modify-guild-member
 * @param channel_id Id of the channel to which the user is used. Set to `0` to disconnect the user
 * @param guild_id Guild id to which the user is connected
 * @param user_id User id, who should be moved
 * @return guild_member returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_member_move(const snowflake channel_id, const snowflake guild_id, const snowflake user_id);

/**
 * @brief Search for guild members based on whether their username or nickname starts with the given string.
 *
 * @note This endpoint is restricted according to whether the `GUILD_MEMBERS` Privileged Intent is enabled for your application.
 * @see dpp::cluster::guild_search_members
 * @see https://discord.com/developers/docs/resources/guild#search-guild-members
 * @param guild_id Guild ID to search in
 * @param query Query string to match username(s) and nickname(s) against
 * @param limit max number of members to return (1-1000)
 * @return guild_member_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_search_members(snowflake guild_id, const std::string& query, uint16_t limit);

/**
 * @brief Get guild invites
 * 
 * Returns a list of invite objects (with invite metadata) for the guild. Requires the `MANAGE_GUILD` permission.
 *
 * @see dpp::cluster::guild_get_invites
 * @see https://discord.com/developers/docs/resources/guild#get-guild-invites
 * @param guild_id Guild ID to get invites for
 * @return invite_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_get_invites(snowflake guild_id);


[[nodiscard]] async<confirmation_callback_t> co_invite_delete(const std::string &invitecode);

/**
 * @brief Get details about an invite
 *
 * @see dpp::cluster::invite_get
 * @see https://discord.com/developers/docs/resources/invite#get-invite
 * @param invite_code Invite code to get information on
 * @return invite returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_invite_get(const std::string &invite_code);

/**
 * @brief Add a reaction to a message. The reaction string must be either an `emojiname:id` or a unicode character.
 *
 * @see dpp::cluster::message_add_reaction
 * @see https://discord.com/developers/docs/resources/channel#create-reaction
 * @param m Message to add a reaction to
 * @param reaction Reaction to add. Emojis should be in the form emojiname:id
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_message_add_reaction(const struct message &m, const std::string &reaction);

/**
 * @brief Add a reaction to a message by id. The reaction string must be either an `emojiname:id` or a unicode character.
 *
 * @see dpp::cluster::message_add_reaction
 * @see https://discord.com/developers/docs/topics/gateway#message-reaction-add
 * @param message_id Message to add reactions to
 * @param channel_id Channel to add reactions to
 * @param reaction Reaction to add. Emojis should be in the form emojiname:id
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_message_add_reaction(snowflake message_id, snowflake channel_id, const std::string &reaction);

/**
 * @brief Send a message to a channel. The callback function is called when the message has been sent
 *
 * @see dpp::cluster::message_create
 * @see https://discord.com/developers/docs/resources/channel#create-message
 * @param m Message to send
 * @return message returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_message_create(const struct message &m);

/**
 * @brief Crosspost a message. The callback function is called when the message has been sent
 *
 * @see dpp::cluster::message_crosspost
 * @see https://discord.com/developers/docs/resources/channel#crosspost-message
 * @param message_id Message to crosspost
 * @param channel_id Channel ID to crosspost from
 * @return message returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_message_crosspost(snowflake message_id, snowflake channel_id);

/**
 * @brief Delete all reactions on a message
 *
 * @see dpp::cluster::message_delete_all_reactions
 * @see https://discord.com/developers/docs/resources/channel#delete-all-reactions
 * @param m Message to delete reactions from
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_message_delete_all_reactions(const struct message &m);

/**
 * @brief Delete all reactions on a message by id
 *
 * @see dpp::cluster::message_delete_all_reactions
 * @see https://discord.com/developers/docs/resources/channel#delete-all-reactions
 * @param message_id Message to delete reactions from
 * @param channel_id Channel to delete reactions from
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_message_delete_all_reactions(snowflake message_id, snowflake channel_id);

/**
 * @brief Bulk delete messages from a channel. The callback function is called when the message has been edited
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 *
 * @note If any message provided older than 2 weeks or any duplicate message ID, it will fail.
 *
 * @see dpp::cluster::message_delete_bulk
 * @see https://discord.com/developers/docs/resources/channel#bulk-delete-messages
 * @param message_ids List of message IDs to delete (at least 2 and at most 100 message IDs)
 * @param channel_id Channel to delete from
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_message_delete_bulk(const std::vector<snowflake> &message_ids, snowflake channel_id);

/**
 * @brief Delete a message from a channel. The callback function is called when the message has been edited
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 *
 * @see dpp::cluster::message_delete
 * @see https://discord.com/developers/docs/resources/channel#delete-message
 * @param message_id Message ID to delete
 * @param channel_id Channel to delete from
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_message_delete(snowflake message_id, snowflake channel_id);

/**
 * @brief Delete own reaction from a message. The reaction string must be either an `emojiname:id` or a unicode character.
 *
 * @see dpp::cluster::message_delete_own_reaction
 * @see https://discord.com/developers/docs/resources/channel#delete-own-reaction
 * @param m Message to delete own reaction from
 * @param reaction Reaction to delete. The reaction should be in the form emojiname:id
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_message_delete_own_reaction(const struct message &m, const std::string &reaction);

/**
 * @brief Delete own reaction from a message by id. The reaction string must be either an `emojiname:id` or a unicode character.
 *
 * @see dpp::cluster::message_delete_own_reaction
 * @see https://discord.com/developers/docs/resources/channel#delete-own-reaction
 * @param message_id Message to delete reactions from
 * @param channel_id Channel to delete reactions from
 * @param reaction Reaction to delete. The reaction should be in the form emojiname:id
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_message_delete_own_reaction(snowflake message_id, snowflake channel_id, const std::string &reaction);

/**
 * @brief Delete a user's reaction from a message. The reaction string must be either an `emojiname:id` or a unicode character
 *
 * @see dpp::cluster::message_delete_reaction
 * @see https://discord.com/developers/docs/resources/channel#delete-user-reaction
 * @param m Message to delete a user's reaction from
 * @param user_id User ID who's reaction you want to remove
 * @param reaction Reaction to remove. Reactions should be in the form emojiname:id
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_message_delete_reaction(const struct message &m, snowflake user_id, const std::string &reaction);

/**
 * @brief Delete a user's reaction from a message by id. The reaction string must be either an `emojiname:id` or a unicode character
 *
 * @see dpp::cluster::message_delete_reaction
 * @see https://discord.com/developers/docs/resources/channel#delete-user-reaction
 * @param message_id Message to delete reactions from
 * @param channel_id Channel to delete reactions from
 * @param user_id User ID who's reaction you want to remove
 * @param reaction Reaction to remove. Reactions should be in the form emojiname:id
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_message_delete_reaction(snowflake message_id, snowflake channel_id, snowflake user_id, const std::string &reaction);

/**
 * @brief Delete all reactions on a message using a particular emoji. The reaction string must be either an `emojiname:id` or a unicode character
 *
 * @see dpp::cluster::message_delete_reaction_emoji
 * @see https://discord.com/developers/docs/resources/channel#delete-all-reactions-for-emoji
 * @param m Message to delete reactions from
 * @param reaction Reaction to delete, in the form emojiname:id or a unicode character
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_message_delete_reaction_emoji(const struct message &m, const std::string &reaction);

/**
 * @brief Delete all reactions on a message using a particular emoji by id. The reaction string must be either an `emojiname:id` or a unicode character
 *
 * @see dpp::cluster::message_delete_reaction_emoji
 * @see https://discord.com/developers/docs/resources/channel#delete-all-reactions-for-emoji
 * @param message_id Message to delete reactions from
 * @param channel_id Channel to delete reactions from
 * @param reaction Reaction to delete, in the form emojiname:id or a unicode character
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_message_delete_reaction_emoji(snowflake message_id, snowflake channel_id, const std::string &reaction);

/**
 * @brief Edit a message on a channel. The callback function is called when the message has been edited
 *
 * @see dpp::cluster::message_edit
 * @see https://discord.com/developers/docs/resources/channel#edit-message
 * @param m Message to edit
 * @return message returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_message_edit(const struct message &m);

/**
 * @brief Edit the flags of a message on a channel. The callback function is called when the message has been edited
 *
 * @param m Message to edit the flags of
 * @return message returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_message_edit_flags(const struct message &m);

/**
 * @brief Get a message
 *
 * @see dpp::cluster::message_get
 * @see https://discord.com/developers/docs/resources/channel#get-channel-message
 * @param message_id Message ID
 * @param channel_id Channel ID
 * @return message returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_message_get(snowflake message_id, snowflake channel_id);

/**
 * @brief Get reactions on a message for a particular emoji. The reaction string must be either an `emojiname:id` or a unicode character
 *
 * @see dpp::cluster::message_get_reactions
 * @see https://discord.com/developers/docs/resources/channel#get-reactions
 * @param m Message to get reactions for
 * @param reaction Reaction should be in the form emojiname:id or a unicode character
 * @param before Reactions before this ID should be retrieved if this is set to non-zero
 * @param after Reactions before this ID should be retrieved if this is set to non-zero
 * @param limit This number of reactions maximum should be returned
 * @return user_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_message_get_reactions(const struct message &m, const std::string &reaction, snowflake before, snowflake after, snowflake limit);

/**
 * @brief Get reactions on a message for a particular emoji by id. The reaction string must be either an `emojiname:id` or a unicode character
 *
 * @see dpp::cluster::message_get_reactions
 * @see https://discord.com/developers/docs/resources/channel#get-reactions
 * @param message_id Message to get reactions for
 * @param channel_id Channel to get reactions for
 * @param reaction Reaction should be in the form emojiname:id or a unicode character
 * @param before Reactions before this ID should be retrieved if this is set to non-zero
 * @param after Reactions before this ID should be retrieved if this is set to non-zero
 * @param limit This number of reactions maximum should be returned
 * @return emoji_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_message_get_reactions(snowflake message_id, snowflake channel_id, const std::string &reaction, snowflake before, snowflake after, snowflake limit);

/**
 * @brief Pin a message
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @see dpp::cluster::message_pin
 * @see https://discord.com/developers/docs/resources/channel#pin-message
 * @param channel_id Channel id to pin message on
 * @param message_id Message id to pin message on
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_message_pin(snowflake channel_id, snowflake message_id);

/**
 * @brief Get multiple messages.
 * 
 * This function will attempt to fetch as many messages as possible using multiple API calls if needed.
 *
 * @see dpp::cluster::messages_get
 * @see https://discord.com/developers/docs/resources/channel#get-channel-messages
 * @param channel_id Channel ID to retrieve messages for
 * @param around Messages should be retrieved around this ID if this is set to non-zero
 * @param before Messages before this ID should be retrieved if this is set to non-zero
 * @param after Messages after this ID should be retrieved if this is set to non-zero
 * @param limit This number of messages maximum should be returned, up to a maximum of 100.
 * @return message_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_messages_get(snowflake channel_id, snowflake around, snowflake before, snowflake after, uint64_t limit);

/**
 * @brief Unpin a message
 * @see dpp::cluster::message_unpin
 * @see https://discord.com/developers/docs/resources/channel#unpin-message
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @param channel_id Channel id to unpin message on
 * @param message_id Message id to unpin message on
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_message_unpin(snowflake channel_id, snowflake message_id);

/**
 * @brief Get a list of users that voted for this specific answer.
 *
 * @param m Message that contains the poll to retrieve the answers from
 * @param answer_id ID of the answer to retrieve votes from (see poll_answer::answer_id)
 * @param after Users after this ID should be retrieved if this is set to non-zero
 * @param limit This number of users maximum should be returned, up to 100
 * @return user_map returned object on completion
 * @see dpp::cluster::poll_get_answer_voters
 * @see https://discord.com/developers/docs/resources/poll#get-answer-voters
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_poll_get_answer_voters(const message& m, uint32_t answer_id, snowflake after, uint64_t limit);

/**
 * @brief Get a list of users that voted for this specific answer.
 *
 * @param message_id ID of the message with the poll to retrieve the answers from
 * @param channel_id ID of the channel with the poll to retrieve the answers from
 * @param answer_id ID of the answer to retrieve votes from (see poll_answer::answer_id)
 * @param after Users after this ID should be retrieved if this is set to non-zero
 * @param limit This number of users maximum should be returned, up to 100
 * @return user_map returned object on completion
 * @see dpp::cluster::poll_get_answer_voters
 * @see https://discord.com/developers/docs/resources/poll#get-answer-voters
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_poll_get_answer_voters(snowflake message_id, snowflake channel_id, uint32_t answer_id, snowflake after, uint64_t limit);

/**
 * @brief Immediately end a poll.
 *
 * @param m Message that contains the poll
 * @return message returned object on completion
 * @see dpp::cluster::poll_end
 * @see https://discord.com/developers/docs/resources/poll#end-poll
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_poll_end(const message &m);

/**
 * @brief Immediately end a poll.
 *
 * @param message_id ID of the message with the poll to end
 * @param channel_id ID of the channel with the poll to end
 * @return message returned object on completion
 * @see dpp::cluster::poll_end
 * @see https://discord.com/developers/docs/resources/poll#end-poll
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_poll_end(snowflake message_id, snowflake channel_id);

/**
 * @brief Get a channel's pins
 * @see dpp::cluster::channel_pins_get
 * @see https://discord.com/developers/docs/resources/channel#get-pinned-messages
 * @param channel_id Channel ID to get pins for
 * @return message_pin_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_channel_pins_get(snowflake channel_id);

/**
 * @brief Get a channel's pins
 * @see dpp::cluster::channel_pins_get
 * @see https://discord.com/developers/docs/resources/channel#get-pinned-messages
 * @param channel_id Channel ID to get pins for
 * @param before Get messages pinned before this timestamp.
 * @param limit Max number of pins to return (1-50). Defaults to 50 if not set.
 * @return message_pin_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_channel_pins_get(snowflake channel_id, std::optional<time_t> before, std::optional<uint64_t> limit);

/**
 * @brief Create a role on a guild
 * 
 * Create a new role for the guild. Requires the `MANAGE_ROLES` permission. Returns the new role object on success.
 * Fires a `Guild Role Create` Gateway event.
 * 
 * @see dpp::cluster::role_create
 * @see https://discord.com/developers/docs/resources/guild#create-guild-role
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @param r Role to create (guild ID is encapsulated in the role object)
 * @return role returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_role_create(const class role &r);

/**
 * @brief Delete a role
 * 
 * Requires the `MANAGE_ROLES` permission. Fires a `Guild Role Delete` Gateway event.
 * 
 * @see dpp::cluster::role_delete
 * @see https://discord.com/developers/docs/resources/guild#delete-guild-role
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @param guild_id Guild ID to delete the role on
 * @param role_id Role ID to delete
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_role_delete(snowflake guild_id, snowflake role_id);

/**
 * @brief Edit a role on a guild
 * 
 * Requires the `MANAGE_ROLES` permission. Returns the updated role on success. Fires a `Guild Role Update` Gateway event.
 * 
 * @see dpp::cluster::role_edit
 * @see https://discord.com/developers/docs/resources/guild#modify-guild-role
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @param r Role to edit
 * @return role returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_role_edit(const class role &r);

/**
 * @brief Edit multiple role's position in a guild. Returns a list of all roles of the guild on success.
 *
 * Modify the positions of a set of role objects for the guild. Requires the `MANAGE_ROLES` permission.
 * Fires multiple `Guild Role Update` Gateway events.
 *
 * @see dpp::cluster::roles_edit_position
 * @see https://discord.com/developers/docs/resources/guild#modify-guild-role-positions
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @param guild_id Guild ID to change the roles position on
 * @param roles Vector of roles to change the positions of
 * @return role_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_roles_edit_position(snowflake guild_id, const std::vector<role> &roles);

/**
 * @brief Get a role for a guild
 *
 * @see dpp::cluster::roles_get
 * @see https://discord.com/developers/docs/resources/guild#get-guild-roles
 * @param guild_id Guild ID to get role for
 * @return role_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_roles_get(snowflake guild_id);

/**
 * @brief Get the application's role connection metadata records
 *
 * @see dpp::cluster::application_role_connection_get
 * @see https://discord.com/developers/docs/resources/application-role-connection-metadata#get-application-role-connection-metadata-records
 * @param application_id The application ID
 * @return application_role_connection_metadata_list returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_application_role_connection_get(snowflake application_id);

/**
 * @brief Update the application's role connection metadata records
 *
 * @see dpp::cluster::application_role_connection_update
 * @see https://discord.com/developers/docs/resources/application-role-connection-metadata#update-application-role-connection-metadata-records
 * @param application_id The application ID
 * @param connection_metadata The application role connection metadata to update
 * @return application_role_connection_metadata_list returned object on completion
 * @note An application can have a maximum of 5 metadata records.
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_application_role_connection_update(snowflake application_id, const std::vector<application_role_connection_metadata> &connection_metadata);

/**
 * @brief Get user application role connection
 *
 * @see dpp::cluster::user_application_role_connection_get
 * @see https://discord.com/developers/docs/resources/user#get-user-application-role-connection
 * @param application_id The application ID
 * @return application_role_connection returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_user_application_role_connection_get(snowflake application_id);

/**
 * @brief Update user application role connection
 *
 * @see dpp::cluster::user_application_role_connection_update
 * @see https://discord.com/developers/docs/resources/user#update-user-application-role-connection
 * @param application_id The application ID
 * @param connection The application role connection to update
 * @return application_role_connection returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_user_application_role_connection_update(snowflake application_id, const application_role_connection &connection);

/**
 * @brief Get all scheduled events for a guild
 * @see dpp::cluster::guild_events_get
 * @see https://discord.com/developers/docs/resources/guild-scheduled-event#list-scheduled-events-for-guild
 * @param guild_id Guild to get events for
 * @return scheduled_event_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_events_get(snowflake guild_id);

/**
 * @brief Create a scheduled event on a guild
 *
 * @see dpp::cluster::guild_event_create
 * @see https://discord.com/developers/docs/resources/guild-scheduled-event#create-guild-scheduled-event
 * @param event Event to create (guild ID must be populated)
 * @return scheduled_event returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_event_create(const scheduled_event& event);

/**
 * @brief Delete a scheduled event from a guild
 *
 * @see dpp::cluster::guild_event_delete
 * @see https://discord.com/developers/docs/resources/guild-scheduled-event#delete-guild-scheduled-event
 * @param event_id Event ID to delete
 * @param guild_id Guild ID of event to delete
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_event_delete(snowflake event_id, snowflake guild_id);

/**
 * @brief Edit/modify a scheduled event on a guild
 *
 * @see dpp::cluster::guild_event_edit
 * @see https://discord.com/developers/docs/resources/guild-scheduled-event#modify-guild-scheduled-event
 * @param event Event to create (event ID and guild ID must be populated)
 * @return scheduled_event returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_event_edit(const scheduled_event& event);

/**
 * @brief Get a scheduled event for a guild
 *
 * @see dpp::cluster::guild_event_get
 * @see https://discord.com/developers/docs/resources/guild-scheduled-event#get-guild-scheduled-event
 * @param guild_id Guild to get event for
 * @param event_id Event ID to get
 * @return scheduled_event returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_event_get(snowflake guild_id, snowflake event_id);

/**
 * @brief Returns all SKUs for a given application.
 * @note Because of how Discord's SKU and subscription systems work, you will see two SKUs for your premium offering.
 * For integration and testing entitlements, you should use the SKU with type: 5.
 *
 * @see dpp::cluster::skus_get
 * @see https://discord.com/developers/docs/monetization/skus#list-skus
 * @return sku_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_skus_get();


[[nodiscard]] async<confirmation_callback_t> co_stage_instance_create(const stage_instance& si);

/**
 * @brief Get the stage instance associated with the channel id, if it exists.
 * @see dpp::cluster::stage_instance_get
 * @see https://discord.com/developers/docs/resources/stage-instance#get-stage-instance
 * @param channel_id ID of the associated channel
 * @return stage_instance returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_stage_instance_get(const snowflake channel_id);


[[nodiscard]] async<confirmation_callback_t> co_stage_instance_edit(const stage_instance& si);

/**
 * @brief Delete a stage instance.
 * @see dpp::cluster::stage_instance_delete
 * @see https://discord.com/developers/docs/resources/stage-instance#delete-stage-instance
 * @param channel_id ID of the associated channel
 * @return confirmation returned object on completion
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_stage_instance_delete(const snowflake channel_id);

/**
 * @brief Create a sticker in a guild
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @see dpp::cluster::guild_sticker_create
 * @see https://discord.com/developers/docs/resources/sticker#create-guild-sticker
 * @param s Sticker to create. Must have its guild ID set.
 * @return sticker returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_sticker_create(const sticker &s);

/**
 * @brief Delete a sticker from a guild
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @see dpp::cluster::guild_sticker_delete
 * @see https://discord.com/developers/docs/resources/sticker#delete-guild-sticker
 * @param sticker_id sticker ID to delete
 * @param guild_id guild ID to delete from
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_sticker_delete(snowflake sticker_id, snowflake guild_id);

/**
 * @brief Get a guild sticker
 * @see dpp::cluster::guild_sticker_get
 * @see https://discord.com/developers/docs/resources/sticker#get-guild-sticker
 * @param id Id of sticker to get.
 * @param guild_id Guild ID of the guild where the sticker is
 * @return sticker returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_sticker_get(snowflake id, snowflake guild_id);

/**
 * @brief Modify a sticker in a guild
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @see dpp::cluster::guild_sticker_modify
 * @see https://discord.com/developers/docs/resources/sticker#modify-guild-sticker
 * @param s Sticker to modify. Must have its guild ID and sticker ID set.
 * @return sticker returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_sticker_modify(const sticker &s);

/**
 * @brief Get all guild stickers
 * @see dpp::cluster::guild_stickers_get
 * @see https://discord.com/developers/docs/resources/sticker#list-guild-stickers
 * @param guild_id Guild ID of the guild where the sticker is
 * @return sticker_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_stickers_get(snowflake guild_id);

/**
 * @brief Get a nitro sticker
 * @see dpp::cluster::nitro_sticker_get
 * @see https://discord.com/developers/docs/resources/sticker#get-sticker
 * @param id Id of sticker to get.
 * @return sticker returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_nitro_sticker_get(snowflake id);

/**
 * @brief Get a list of available sticker packs
 * @see dpp::cluster::sticker_packs_get
 * @see https://discord.com/developers/docs/resources/sticker#list-sticker-packs
 * @return sticker_pack_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_sticker_packs_get();

/**
 * @brief Create a new guild based on a template.
 * @note This endpoint can be used only by bots in less than 10 guilds.
 * @see dpp::cluster::guild_create_from_template
 * @see https://discord.com/developers/docs/resources/guild-template#create-guild-from-guild-template
 * @param code Template code to create guild from
 * @param name Guild name to create
 * @return guild returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_create_from_template(const std::string &code, const std::string &name);

/**
 * @brief Creates a template for the guild
 *
 * @see dpp::cluster::guild_template_create
 * @see https://discord.com/developers/docs/resources/guild-template#create-guild-template
 * @param guild_id Guild to create template from
 * @param name Template name to create
 * @param description Description of template to create
 * @return dtemplate returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_template_create(snowflake guild_id, const std::string &name, const std::string &description);

/**
 * @brief Deletes the template
 *
 * @see dpp::cluster::guild_template_delete
 * @see https://discord.com/developers/docs/resources/guild-template#delete-guild-template
 * @param guild_id Guild ID of template to delete
 * @param code Template code to delete
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_template_delete(snowflake guild_id, const std::string &code);

/**
 * @brief Modifies the template's metadata.
 *
 * @see dpp::cluster::guild_template_modify
 * @see https://discord.com/developers/docs/resources/guild-template#modify-guild-template
 * @param guild_id Guild ID of template to modify
 * @param code Template code to modify
 * @param name New name of template
 * @param description New description of template
 * @return dtemplate returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_template_modify(snowflake guild_id, const std::string &code, const std::string &name, const std::string &description);

/**
 * @brief Get guild templates
 *
 * @see dpp::cluster::guild_templates_get
 * @see https://discord.com/developers/docs/resources/guild-template#get-guild-templates
 * @param guild_id Guild ID to get templates for
 * @return dtemplate_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_templates_get(snowflake guild_id);

/**
 * @brief Syncs the template to the guild's current state.
 *
 * @see dpp::cluster::guild_template_sync
 * @see https://discord.com/developers/docs/resources/guild-template#sync-guild-template
 * @param guild_id Guild to synchronise template for
 * @param code Code of template to synchronise
 * @return dtemplate returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_template_sync(snowflake guild_id, const std::string &code);

/**
 * @brief Get a template
 * @see dpp::cluster::template_get
 * @see https://discord.com/developers/docs/resources/guild-template#get-guild-template
 * @param code Template code
 * @return dtemplate returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_template_get(const std::string &code);

/**
 * @brief Join a thread
 * @see dpp::cluster::current_user_join_thread
 * @see https://discord.com/developers/docs/resources/channel#join-thread
 * @param thread_id Thread ID to join
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_current_user_join_thread(snowflake thread_id);

/**
 * @brief Leave a thread
 * @see dpp::cluster::current_user_leave_thread
 * @see https://discord.com/developers/docs/resources/channel#leave-thread
 * @param thread_id Thread ID to leave
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_current_user_leave_thread(snowflake thread_id);

/**
 * @brief Get all active threads in the guild, including public and private threads. Threads are ordered by their id, in descending order.
 * @see dpp::cluster::threads_get_active
 * @see https://discord.com/developers/docs/resources/guild#list-active-guild-threads
 * @param guild_id Guild to get active threads for
 * @return active_threads returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_threads_get_active(snowflake guild_id);

/**
 * @brief Get private archived threads in a channel which current user has joined (Sorted by ID in descending order)
 * @see dpp::cluster::threads_get_joined_private_archived
 * @see https://discord.com/developers/docs/resources/channel#list-joined-private-archived-threads
 * @param channel_id Channel to get public archived threads for
 * @param before_id Get threads before this id
 * @param limit Number of threads to get
 * @return thread_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_threads_get_joined_private_archived(snowflake channel_id, snowflake before_id, uint16_t limit);

/**
 * @brief Get private archived threads in a channel (Sorted by archive_timestamp in descending order)
 * @see dpp::cluster::threads_get_private_archived
 * @see https://discord.com/developers/docs/resources/channel#list-private-archived-threads
 * @param channel_id Channel to get public archived threads for
 * @param before_timestamp Get threads archived before this timestamp
 * @param limit Number of threads to get
 * @return thread_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_threads_get_private_archived(snowflake channel_id,  time_t before_timestamp, uint16_t limit);

/**
 * @brief Get public archived threads in a channel (Sorted by archive_timestamp in descending order)
 * @see dpp::cluster::threads_get_public_archived
 * @see https://discord.com/developers/docs/resources/channel#list-public-archived-threads
 * @param channel_id Channel to get public archived threads for
 * @param before_timestamp Get threads archived before this timestamp
 * @param limit Number of threads to get
 * @return thread_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_threads_get_public_archived(snowflake channel_id, time_t before_timestamp, uint16_t limit);

/**
 * @brief Get a thread member
 * @see dpp::cluster::thread_member_get
 * @see https://discord.com/developers/docs/resources/channel#get-thread-member
 * @param thread_id Thread to get member for
 * @param user_id ID of the user to get
 * @return thread_member returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_thread_member_get(const snowflake thread_id, const snowflake user_id);

/**
 * @brief Get members of a thread
 * @see dpp::cluster::thread_members_get
 * @see https://discord.com/developers/docs/resources/channel#list-thread-members
 * @param thread_id Thread to get members for
 * @return thread_member_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_thread_members_get(snowflake thread_id);

/**
 * @brief Create a thread in a forum or media channel
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 *
 * @see dpp::cluster::thread_create_in_forum
 * @see https://discord.com/developers/docs/resources/channel#start-thread-in-forum-channel
 * @param thread_name Name of the forum thread
 * @param channel_id Forum channel in which thread to create
 * @param msg The message to start the thread with
 * @param auto_archive_duration Duration to automatically archive the thread after recent activity
 * @param rate_limit_per_user amount of seconds a user has to wait before sending another message (0-21600); bots, as well as users with the permission manage_messages, manage_thread, or manage_channel, are unaffected
 * @param applied_tags List of IDs of forum tags (dpp::forum_tag) to apply to this thread
 * @return thread returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_thread_create_in_forum(const std::string& thread_name, snowflake channel_id, const message& msg, auto_archive_duration_t auto_archive_duration, uint16_t rate_limit_per_user, std::vector<snowflake> applied_tags = {});

/**
 * @brief Create a thread
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 *
 * @see dpp::cluster::thread_create
 * @see https://discord.com/developers/docs/resources/channel#start-thread-without-message
 * @param thread_name Name of the thread
 * @param channel_id Channel in which thread to create
 * @param auto_archive_duration Duration after which thread auto-archives. Can be set to - 60, 1440 (for boosted guilds can also be: 4320, 10080)
 * @param thread_type Type of thread - CHANNEL_PUBLIC_THREAD, CHANNEL_ANNOUNCEMENT_THREAD, CHANNEL_PRIVATE_THREAD
 * @param invitable whether non-moderators can add other non-moderators to a thread; only available when creating a private thread
 * @param rate_limit_per_user amount of seconds a user has to wait before sending another message (0-21600); bots, as well as users with the permission manage_messages, manage_thread, or manage_channel, are unaffected
 * @return thread returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_thread_create(const std::string& thread_name, snowflake channel_id, uint16_t auto_archive_duration, channel_type thread_type, bool invitable, uint16_t rate_limit_per_user);

/**
 * @brief Edit a thread
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 *
 * @see dpp::cluster::thread_edit
 * @see https://discord.com/developers/docs/topics/threads#editing-deleting-threads
 * @param t Thread to edit
 * @return thread returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_thread_edit(const thread &t);

/**
 * @brief Create a thread with a message (Discord: ID of a thread is same as message ID)
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @see dpp::cluster::thread_create_with_message
 * @see https://discord.com/developers/docs/resources/channel#start-thread-from-message
 * @param thread_name Name of the thread
 * @param channel_id Channel in which thread to create
 * @param message_id message to start thread with
 * @param auto_archive_duration Duration after which thread auto-archives. Can be set to - 60, 1440 (for boosted guilds can also be: 4320, 10080)
 * @param rate_limit_per_user amount of seconds a user has to wait before sending another message (0-21600); bots, as well as users with the permission manage_messages, manage_thread, or manage_channel, are unaffected
 * @return thread returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_thread_create_with_message(const std::string& thread_name, snowflake channel_id, snowflake message_id, uint16_t auto_archive_duration, uint16_t rate_limit_per_user);

/**
 * @brief Add a member to a thread
 * @see dpp::cluster::thread_member_add
 * @see https://discord.com/developers/docs/resources/channel#add-thread-member
 * @param thread_id Thread ID to add to
 * @param user_id Member ID to add
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_thread_member_add(snowflake thread_id, snowflake user_id);

/**
 * @brief Remove a member from a thread
 * @see dpp::cluster::thread_member_remove
 * @see https://discord.com/developers/docs/resources/channel#remove-thread-member
 * @param thread_id Thread ID to remove from
 * @param user_id Member ID to remove
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_thread_member_remove(snowflake thread_id, snowflake user_id);

/**
 * @brief Get the thread specified by thread_id. This uses the same call as dpp::cluster::channel_get but returns a thread object.
 * @see dpp::cluster::thread_get
 * @see https://discord.com/developers/docs/resources/channel#get-channel
 * @param thread_id The id of the thread to obtain.
 * @return thread returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_thread_get(snowflake thread_id);

/**
 * @brief Edit current (bot) user.
 *
 * Modify the requester's user account settings. Returns a dpp::user object on success.
 * Fires a User Update Gateway event.
 *
 * @note There appears to be no limit to the image size, however, if your image cannot be processed/uploaded in time, you will receive a malformed http request.
 *
 * @see dpp::cluster::current_user_edit
 * @see https://discord.com/developers/docs/resources/user#modify-current-user
 * @param nickname Nickname to set
 * @param avatar_blob Avatar data to upload
 * @param avatar_type Type of image for avatar. It can be one of `i_gif`, `i_jpg` or `i_png`.
 * @param banner_blob Banner data to upload
 * @param banner_type Type of image for Banner. It can be one of `i_gif`, `i_jpg` or `i_png`.
 * @return user returned object on completion
 	 * @throw dpp::length_exception Image data is larger than the maximum size of 256 kilobytes
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_current_user_edit(const std::string &nickname, const std::string& avatar_blob = "", const image_type avatar_type = i_png, const std::string& banner_blob = "", const image_type banner_type = i_png);

/**
 * @brief Get current (bot) application
 *
 * @see dpp::cluster::current_application_get
 * @see https://discord.com/developers/docs/topics/oauth2#get-current-bot-application-information
 * @return application returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_current_application_get();

/**
 * @brief Get current (bot) user
 *
 * @see dpp::cluster::current_user_get
 * @see https://discord.com/developers/docs/resources/user#get-current-user
 * @return user_identified returned object on completion
 * @note The user_identified object is a subclass of dpp::user which contains further details if you have the oauth2 identify or email scopes.
 * If you do not have these scopes, these fields are empty. You can safely convert a user_identified to user with `dynamic_cast`.
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_current_user_get();

/**
 * @brief Set the bot's voice state on a stage channel
 * 
 * **Caveats**
 * 
 * There are currently several caveats for this endpoint:
 * 
 * - `channel_id` must currently point to a stage channel.
 * - current user must already have joined `channel_id`.
 * - You must have the `MUTE_MEMBERS` permission to unsuppress yourself. You can always suppress yourself.
 * - You must have the `REQUEST_TO_SPEAK` permission to request to speak. You can always clear your own request to speak.
 * - You are able to set `request_to_speak_timestamp` to any present or future time.
 *
 * @see dpp::cluster::current_user_set_voice_state
 * @see https://discord.com/developers/docs/resources/guild#modify-current-user-voice-state 
 * @param guild_id Guild to set voice state on
 * @param channel_id Stage channel to set voice state on
 * @return confirmation returned object on completion
 * @param suppress True if the user's audio should be suppressed, false if it should not
 * @param request_to_speak_timestamp The time at which we requested to speak, or 0 to clear the request. The time set here must be the current time or in the future.
 * @throw std::logic_exception You attempted to set a request_to_speak_timestamp in the past which is not the value of 0.
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_current_user_set_voice_state(snowflake guild_id, snowflake channel_id, bool suppress = false, time_t request_to_speak_timestamp = 0);

/**
 * @brief Get the bot's voice state in a guild without a Gateway connection
 *
 * @see dpp::cluster::current_user_get_voice_state
 * @see https://discord.com/developers/docs/resources/voice#get-current-user-voice-state
 * @param guild_id Guild to get the voice state for
 * @return voicestate returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_current_user_get_voice_state(snowflake guild_id);

/**
 * @brief Set a user's voice state on a stage channel
 *
 * **Caveats**
 * 
 * There are currently several caveats for this endpoint:
 * 
 * - `channel_id` must currently point to a stage channel.
 * - User must already have joined `channel_id`.
 * - You must have the `MUTE_MEMBERS` permission. (Since suppression is the only thing that is available currently)
 * - When unsuppressed, non-bot users will have their `request_to_speak_timestamp` set to the current time. Bot users will not.
 * - When suppressed, the user will have their `request_to_speak_timestamp` removed.
 * 
 * @see dpp::cluster::user_set_voice_state
 * @see https://discord.com/developers/docs/resources/guild#modify-user-voice-state
 * @param user_id The user to set the voice state of
 * @param guild_id Guild to set voice state on
 * @param channel_id Stage channel to set voice state on
 * @return confirmation returned object on completion
 * @param suppress True if the user's audio should be suppressed, false if it should not
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_user_set_voice_state(snowflake user_id, snowflake guild_id, snowflake channel_id, bool suppress = false);

/**
 * @brief Get a user's voice state in a guild without a Gateway connection
 *
 * @see dpp::cluster::user_get_voice_state
 * @see https://discord.com/developers/docs/resources/voice#get-user-voice-state
 * @param guild_id Guild to get the voice state for
 * @param user_id The user to get the voice state of
 * @return voicestate returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_user_get_voice_state(snowflake guild_id, snowflake user_id);

/**
 * @brief Get current user's connections (linked accounts, e.g. steam, xbox).
 * This call requires the oauth2 `connections` scope and cannot be executed
 * against a bot token.
 * @see dpp::cluster::current_user_connections_get
 * @see https://discord.com/developers/docs/resources/user#get-user-connections
 * @return connection_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_current_user_connections_get();

/**
 * @brief Get current (bot) user guilds
 * @see dpp::cluster::current_user_get_guilds
 * @see https://discord.com/developers/docs/resources/user#get-current-user-guilds
 * @return guild_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_current_user_get_guilds();

/**
 * @brief Leave a guild
 * @see dpp::cluster::current_user_leave_guild
 * @see https://discord.com/developers/docs/resources/user#leave-guild
 * @param guild_id Guild ID to leave
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_current_user_leave_guild(snowflake guild_id);

/**
 * @brief Get a user by id, without using the cache
 *
 * @see dpp::cluster::user_get
 * @see https://discord.com/developers/docs/resources/user#get-user
 * @param user_id User ID to retrieve
 * @return user_identified returned object on completion
 * @note The user_identified object is a subclass of dpp::user which contains further details if you have the oauth2 identify or email scopes.
 * If you do not have these scopes, these fields are empty. You can safely convert a user_identified to user with `dynamic_cast`.
 * @note unless you want something special from `dpp::user_identified` or you've turned off caching, you have no need to call this.
 * Call `dpp::find_user` instead that looks up the user in the cache rather than a REST call.
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_user_get(snowflake user_id);

/**
 * @brief Get a user by id, checking in the cache first
 *
 * @see dpp::cluster::user_get_cached
 * @see https://discord.com/developers/docs/resources/user#get-user
 * @param user_id User ID to retrieve
 * @return user_identified returned object on completion
 * @note The user_identified object is a subclass of dpp::user which contains further details if you have the oauth2 identify or email scopes.
 * If you do not have these scopes, these fields are empty. You can safely convert a user_identified to user with `dynamic_cast`.
 * @note If the user is found in the cache, special values set in `dpp::user_identified` will be undefined. This call should be used
 * where you want to for example resolve a user who may no longer be in the bot's guilds, for something like a ban log message.
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_user_get_cached(snowflake user_id);

/**
 * @brief Get all voice regions
 * @see dpp::cluster::get_voice_regions
 * @see https://discord.com/developers/docs/resources/voice#list-voice-regions
 * @return voiceregion_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_get_voice_regions();

/**
 * @brief Get guild voice regions.
 * 
 * Voice regions per guild are somewhat deprecated in preference of per-channel voice regions.
 * Returns a list of voice region objects for the guild. Unlike the similar /voice route, this returns VIP servers when
 * the guild is VIP-enabled.
 *
 * @see dpp::cluster::guild_get_voice_regions
 * @see https://discord.com/developers/docs/resources/guild#get-guild-voice-regions
 * @param guild_id Guild ID to get voice regions for
 * @return voiceregion_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_guild_get_voice_regions(snowflake guild_id);


[[nodiscard]] async<confirmation_callback_t> co_create_webhook(const class webhook &wh);

/**
 * @brief Delete a webhook
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @see dpp::cluster::delete_webhook
 * @see https://discord.com/developers/docs/resources/webhook#delete-webhook
 * @param webhook_id Webhook ID to delete
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_delete_webhook(snowflake webhook_id);

/**
 * @brief Delete webhook message
 *
 * @see dpp::cluster::delete_webhook_message
 * @see https://discord.com/developers/docs/resources/webhook#delete-webhook-message
 * @param wh Webhook to delete message for
 * @param message_id Message ID to delete
 * @param thread_id ID of the thread the message is in
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_delete_webhook_message(const class webhook &wh, snowflake message_id, snowflake thread_id = 0);

/**
 * @brief Delete webhook with token
 * @see dpp::cluster::delete_webhook_with_token
 * @see https://discord.com/developers/docs/resources/webhook#delete-webhook-with-token
 * @param webhook_id Webhook ID to delete
 * @param token Token of webhook to delete
 * @return confirmation returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_delete_webhook_with_token(snowflake webhook_id, const std::string &token);

/**
 * @brief Edit webhook
 * @note This method supports audit log reasons set by the cluster::set_audit_reason() method.
 * @see dpp::cluster::edit_webhook
 * @see https://discord.com/developers/docs/resources/webhook#modify-webhook
 * @param wh Webhook to edit
 * @return webhook returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_edit_webhook(const class webhook& wh);

/**
 * @brief Edit webhook message
 *
 * When the content field is edited, the mentions array in the message object will be reconstructed from scratch based on
 * the new content. The allowed_mentions field of the edit request controls how this happens. If there is no explicit
 * allowed_mentions in the edit request, the content will be parsed with default allowances, that is, without regard to
 * whether or not an allowed_mentions was present in the request that originally created the message.
 * 
 * @see dpp::cluster::edit_webhook_message
 * @see https://discord.com/developers/docs/resources/webhook#edit-webhook-message
 * @note the attachments array must contain all attachments that should be present after edit, including retained and new attachments provided in the request body.
 * @param wh Webhook to edit message for
 * @param m New message
 * @param thread_id ID of the thread the message is in
 * @return message returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_edit_webhook_message(const class webhook &wh, const struct message &m, snowflake thread_id = 0);

/**
 * @brief Edit webhook with token (token is encapsulated in the webhook object)
 * @see dpp::cluster::edit_webhook_with_token
 * @see https://discord.com/developers/docs/resources/webhook#modify-webhook-with-token
 * @param wh Webhook to edit (should include token)
 * @return webhook returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_edit_webhook_with_token(const class webhook& wh);

/**
 * @brief Execute webhook
 *
 * @see dpp::cluster::execute_webhook
 * @see https://discord.com/developers/docs/resources/webhook#execute-webhook
 * @param wh Webhook to execute
 * @param m Message to send
 * @param wait waits for server confirmation of message send before response, and returns the created message body
 * @param thread_id Send a message to the specified thread within a webhook's channel. The thread will automatically be unarchived
 * @param thread_name Name of thread to create (requires the webhook channel to be a forum channel)
 * @return message returned object on completion
 * @note If the webhook channel is a forum channel, you must provide either `thread_id` or `thread_name`. If `thread_id` is provided, the message will send in that thread. If `thread_name` is provided, a thread with that name will be created in the forum channel.
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_execute_webhook(const class webhook &wh, const struct message &m, bool wait = false, snowflake thread_id = 0, const std::string& thread_name = "");

/**
 * @brief Get channel webhooks
 * @see dpp::cluster::get_channel_webhooks
 * @see https://discord.com/developers/docs/resources/webhook#get-guild-webhooks
 * @param channel_id Channel ID to get webhooks for
 * @return webhook_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_get_channel_webhooks(snowflake channel_id);

/**
 * @brief Get guild webhooks
 * @see dpp::cluster::get_guild_webhooks
 * @see https://discord.com/developers/docs/resources/webhook#get-guild-webhooks
 * @param guild_id Guild ID to get webhooks for
 * @return webhook_map returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_get_guild_webhooks(snowflake guild_id);

/**
 * @brief Get webhook
 * @see dpp::cluster::get_webhook
 * @see https://discord.com/developers/docs/resources/webhook#get-webhook
 * @param webhook_id Webhook ID to get
 * @return webhook returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_get_webhook(snowflake webhook_id);

/**
 * @brief Get webhook message
 *
 * @see dpp::cluster::get_webhook_message
 * @see https://discord.com/developers/docs/resources/webhook#get-webhook-message
 * @param wh Webhook to get the original message for
 * @param message_id The message ID
 * @param thread_id ID of the thread the message is in
 * @return message returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_get_webhook_message(const class webhook &wh, snowflake message_id, snowflake thread_id = 0);

/**
 * @brief Get webhook using token
 * @see dpp::cluster::get_webhook_with_token
 * @see https://discord.com/developers/docs/resources/webhook#get-webhook-with-token
 * @param webhook_id Webhook ID to retrieve
 * @param token Token of webhook
 * @return webhook returned object on completion
 * \memberof dpp::cluster
 */
[[nodiscard]] async<confirmation_callback_t> co_get_webhook_with_token(snowflake webhook_id, const std::string &token);


/* End of auto-generated definitions */
[[nodiscard]] async<http_request_completion_t> co_request(const std::string &url, http_method method, const std::string &postdata = "", const std::string &mimetype = "text/plain", const std::multimap<std::string, std::string> &headers = {}, const std::string &protocol = "1.1");

